package com.kh.pajx.sop.base;

import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.util.Assert;

import com.kh.pajx.sop.domain.PageBean;
import com.kh.pajx.sop.util.page.QueryHelper;
import com.kh.pajx.sop.util.page.QueryHelperForManyTable;

/**
 * 
 * @param <T>
 * @author: azzcsimp
 * @Createdate: 2014年6月12日 下午3:34:16
 */
@SuppressWarnings("unchecked")
public abstract class BaseDaoImpl<T> implements IBaseDao<T> {

	@Resource
	private SessionFactory sessionFactory;

	private Class<T> clazz;

	/**
	 * 该类初始化时通过反射机制获取T的真实类型
	 * 
	 * @author: azzcsimp
	 * @Createdate: 2014年6月12日 下午3:58:01
	 */
	public BaseDaoImpl() {
		// 获取当前new的对象的泛型的父类类型
		ParameterizedType pt = (ParameterizedType) this.getClass()
				.getGenericSuperclass();
		// 获取第一个类型参数的真实类型
		this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
	}

	@Override
	public void save(T entity) {
		getSession().save(entity);
		getSession().flush();
	}

	@Override
	public void delete(Long id) {
		Object obj = getById(id);
		if (obj != null) {
			getSession().delete(obj);
			getSession().flush();
		}
	}

	@Override
	public void delete(String uuid) {
		Object obj = getById(uuid);
		if (obj != null) {
			getSession().delete(obj);
			getSession().flush();
		}
	}

	@Override
	public void update(T entity) {
		getSession().update(entity);
		getSession().flush();
	}

	@Override
	public T getById(Long id) {
		if (id == null) {
			return null;
		} else {
			return (T) getSession().get(clazz, id);
		}
	}

	@Override
	public T getById(String uuid) {
		if (uuid == null) {
			return null;
		} else {
			return (T) getSession().get(clazz, uuid);
		}
	}

	@Override
	public List<T> getByIds(Long[] ids) {
		if (ids == null || ids.length == 0) {
			return Collections.EMPTY_LIST;
		}

		return getSession().createQuery(//
				"FROM " + clazz.getSimpleName() + " WHERE id IN(:ids)")//
				.setParameterList("ids", ids)//
				.list();
	}
	
	@Override
	public List<T> getByIds(String[] uuids){
		if(uuids == null || uuids.length == 0){
			return Collections.EMPTY_LIST;
		}
		return getSession().createQuery(//
				"FROM " + clazz.getSimpleName() + " WHERE id IN(:uuids)")//
				.setParameterList("uuids", uuids)//
				.list();
	}

	@Override
	public List<T> findAll() {
		return getSession().createQuery(//
				"FROM " + clazz.getSimpleName())//
				.list();
	}

	@Override
	public PageBean getPageBean(int pageNum, int pageSize,
			QueryHelper queryHelper) {
		// 参数列表
		List<Object> parameters = queryHelper.getParameters();
		// 查询本页的数据列表
		Query listQuery = getSession().createQuery(
				queryHelper.getListQueryHql()); // 创建查询对象
		if (parameters != null) { // 设置参数
			for (int i = 0; i < parameters.size(); i++) {
				/* //这里考虑传入的参数是什么类型，不同类型使用的方法不同  
				if(parameters.get(i) instanceof Object[]){
					检测为数组
					listQuery.setParameterList("in", (Object[])parameters.get(i));
				}else if(parameters.get(i) instanceof Collection<?>){
					检测为集合
					listQuery.setParameterList("in",(Collection<?>)parameters.get(i));
				}else{
					检测为普通
					listQuery.setParameter(i, parameters.get(i));
				}*/
				listQuery.setParameter(i, parameters.get(i));
			}
		}
		
		// in关键字Where条件
		Map<String,List> inMap  = queryHelper.getInMap();
		for (String key : inMap.keySet()) {
			listQuery.setParameterList(key, inMap.get(key));
		}
		listQuery.setFirstResult((pageNum - 1) * pageSize);
		listQuery.setMaxResults(pageSize);
		List list = listQuery.list(); // 执行查询

		// 查询总记录数量
		Query countQuery = getSession().createQuery(
				queryHelper.getCountQueryHql());
		if (parameters != null) { // 设置参数
			for (int i = 0; i < parameters.size(); i++) {
				/*if(parameters.get(i) instanceof Object[]){
					countQuery.setParameterList("in", (Object[])parameters.get(i));
				}else if(parameters.get(i) instanceof List){
					countQuery.setParameterList("in",(List)parameters.get(i));
				}else{
					countQuery.setParameter(i, parameters.get(i));
				}*/
				countQuery.setParameter(i, parameters.get(i));
			}
		}
		
		for (String key : inMap.keySet()) {
			countQuery.setParameterList(key, inMap.get(key));
		}
		Long count = (Long) countQuery.uniqueResult(); // 执行查询

		return new PageBean(pageNum, pageSize, count.intValue(), list);
	}

	@Override
	public PageBean getPageBean(int pageNum, int pageSize, String listHQL,
			String countHQL) {

		// 查询本页的数据列表
		Query listQuery = getSession().createQuery(listHQL); // 创建查询对象
		listQuery.setFirstResult((pageNum - 1) * pageSize);
		listQuery.setMaxResults(pageSize);
		List list = listQuery.list(); // 执行查询

		// 查询总记录数量
		Query countQuery = getSession().createQuery(countHQL);
		Long count = (Long) countQuery.uniqueResult(); // 执行查询

		return new PageBean(pageNum, pageSize, count.intValue(), list);
	}

	/**
	 * 
	 * @see com.kh.pajx.sop.base.IBaseDao#getPageBean(int, int, com.kh.pajx.sop.util.page.QueryHelperForManyTable)
	 */
	@Override
	public PageBean getPageBean(int pageNum, int pageSize,
			QueryHelperForManyTable queryHelper) {
		// 参数列表
		List<Object> parameters = queryHelper.getParameters();

		// 查询本页的数据列表
		Query listQuery = getSession().createQuery(
				queryHelper.getListQueryHql()); // 创建查询对象
		if (parameters != null) { // 设置参数
			for (int i = 0; i < parameters.size(); i++) {
				listQuery.setParameter(i, parameters.get(i));
			}
		}
		
		// in关键字Where条件
		Map<String,List> inMap  = queryHelper.getInMap();
		for (String key : inMap.keySet()) {
			listQuery.setParameterList(key, inMap.get(key));
		}
		
		listQuery.setFirstResult((pageNum - 1) * pageSize);
		listQuery.setMaxResults(pageSize);
		List list = listQuery.list(); // 执行查询

		// 查询总记录数量
		Query countQuery = getSession().createQuery(
				queryHelper.getCountQueryHql());
		if (parameters != null) { // 设置参数
			for (int i = 0; i < parameters.size(); i++) {
				countQuery.setParameter(i, parameters.get(i));
			}
		}
		for (String key : inMap.keySet()) {
			countQuery.setParameterList(key, inMap.get(key));
		}
		Long count = (Long) countQuery.uniqueResult(); // 执行查询

		return new PageBean(pageNum, pageSize, count.intValue(), list);
		
	}
	
	@Override
	public List<T> findListByHql(String queryString, Object... values){
		// queryString 不能为 null 且必须至少包含一个非空格的字符，否则抛出异常； 
		Assert.hasText(queryString);
		//List<T> list = new ArrayList();//Collections.EMPTY_LIST
		Query queryObject = getSession().createQuery(queryString);
		if (values != null && values.length >0 ) {
			for (int i = 0; i < values.length; i++) {
				queryObject.setParameter(i, values[i]);
			}
		}
		return queryObject.list();
	}
	
	@Override
	public List findListByHql2(String queryString, Object... values){
		// queryString 不能为 null 且必须至少包含一个非空格的字符，否则抛出异常； 
		Assert.hasText(queryString);
		//List<T> list = new ArrayList();//Collections.EMPTY_LIST
		Query queryObject = getSession().createQuery(queryString);
		if (values != null && values.length >0 ) {
			for (int i = 0; i < values.length; i++) {
				queryObject.setParameter(i, values[i]);
			}
		}
		return queryObject.list();
	}

	/** 根据语句查询，结果返回一个集合  hql*/
	public List<T> findList(String hql) {
		List results = new ArrayList();
		try {
			results = getSession().createQuery(hql).list();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return results;
	}

	/** 根据语句查询，结果返回一个集合  sql*/
	public List getByJdbcSQL(String sql) {
		List pojolist = new ArrayList();
		Connection con = null;
		PreparedStatement pst = null;
		ResultSet rs = null;
		ResultSetMetaData rsmd = null;
		Session session = null;
		session = getSession().getSessionFactory().openSession();
		con = session.connection();
		try {
			pst = con.prepareStatement(sql);
			rs = pst.executeQuery();
			rsmd = rs.getMetaData();
			int count = rsmd.getColumnCount();
			while (rs.next()) {
				List temp_entity = new ArrayList();
				for (int i = 1; i <= count; i++) {
					temp_entity.add(rs.getString(i));
				}
				pojolist.add(temp_entity);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {

			try {
				if (rs != null) {
					rs.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
			try {
				if (pst != null) {
					pst.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
			try {
				if (session != null) {
					session.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return pojolist;
	}

	/**
	 * 获取当前可用的Session对象
	 * 
	 * @return
	 * @author: azzcsimp
	 * @Createdate: 2014年6月12日 下午3:49:53
	 */
	protected Session getSession() {
		return sessionFactory.getCurrentSession();
	}

}
